package com.candy.model.impl;

import com.candy.dao.AccountDao;
import com.candy.dao.impl.AccountDaoImpl;
import com.candy.model.AccountService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

/**
 * 基于xml方式的配置：
 *  <bean  id="accountService" class="com.candy.model.impl.AccountServiceImpl" scope="singleton" init-method="startMethod" destroy-method="endMethod">
 *         <property name="age" value="26"></property>
 *         <property name="name" value="赵四"></property>
 *         <property name="birthday" ref="now"></property>
 * </bean
 * 使用注解方式进行配置时，与xml的作用是一致的
 * 针对与注解方式的配置，我们可以将注解大致分为四类、
 * 用于对象创建的
 *        作用和bean标签的作用是一致的
 *
 *        Component:
 *                 作用：用于把当前类对象存入spring容器中
 *                 属性：
 *                value：用于指定bean的id。当我们不写时，它的默认值是当前类名，且首字母改小写。
 *        Controller、Service、Repository
 *        他们三个注解都是针对一个的衍生注解，他们的作用及属性都是一模一样的。他们只不过是提供了更加明确的语义化。
 *        @Controller：一般用于表现层的注解。
 *        @Service：一般用于业务层的注解。
 *        @Repository：一般用于持久层的注解。
 * 细节：如果注解中有且只有一个属性要赋值时，且名称是 value，value 在赋值是可以不写。
 *
 * 用于数据注入的
 *       作用和property标签的作用是一致的
 *       @Autowired
 *       作用：
 * 自动按照类型注入。当使用注解注入属性时，set 方法可以省略。
 * 它只能注入其他 bean 类型。
 * 当有多个类型匹配时，
 * 使用要注入的对象变量名称作为 bean 的 id，在 spring 容器查找，找到了也可以注入成功。找不到就报错。
 * @Qualifier
 * 作用：
 * 在自动按照类型注入的基础之上，再按照 Bean 的 id 注入。它在给字段注入时不能独立使用，必须和
 * @Autowire 一起使用；但是给方法参数注入时，可以独立使用。
 *
 * @Resource
 * 作用：
 * 直接按照 Bean 的 id 注入。它也只能注入其他 bean 类型。属性：
 * name：指定 bean 的 id。
 * @Value
 * 作用：
 * 注入基本数据类型和 String 类型数据的属性：
 * 还可以注入bean类型的数据，在注入bean类型数据时，需要使用#{}进行指定需要注入的bean的id
 * value：用于指定值
 *
 * 用于改变作用范围的
 *       与scope属性的作用是一致的
 *       @Scope
 *       作用：
 * 指定 bean 的作用范围。属性：
 * value：指定范围的值。
 * 取值：singleton prototype request session globalsession
 *
 * 声明周期相关的
 *       与init-method、destroy-method的作用是一样的
 *
 *      @PostConstruct
 *       作用：
 * 用于指定初始化方法。
 * @PreDestroy
 * 作用：
 * 用于指定销毁方法。
 */
@Service("accountService")
public class AccountServiceImpl implements AccountService {
    @Value("张三")
    private String name;
    private Integer age;
    private Date birthday;
    private String[] myStrs;
    private List<String> myList;
    private Set<String> mySet;
    private Map<String,String> myMap;
    private Properties myProps;

//    @Autowired
//    @Qualifier(value = "accountDaoImpl")
//    @Resource(name = "accountDaoImpl")
    @Value("#{accountDao}")
    private AccountDao accountDaoImpl22222;

    public AccountServiceImpl() {
    }

    public AccountServiceImpl(String name, Integer age, Date birthday) {
        this.name = name;
        this.age = age;
        this.birthday = birthday;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    public String[] getMyStrs() {
        return myStrs;
    }

    public void setMyStrs(String[] myStrs) {
        this.myStrs = myStrs;
    }

    public List<String> getMyList() {
        return myList;
    }

    public void setMyList(List<String> myList) {
        this.myList = myList;
    }

    public Set<String> getMySet() {
        return mySet;
    }

    public void setMySet(Set<String> mySet) {
        this.mySet = mySet;
    }

    public Map<String, String> getMyMap() {
        return myMap;
    }

    public void setMyMap(Map<String, String> myMap) {
        this.myMap = myMap;
    }

    public Properties getMyProps() {
        return myProps;
    }

    public void setMyProps(Properties myProps) {
        this.myProps = myProps;
    }

//    public AccountDao getAccountDao() {
//        return accountDao;
//    }
//
//    public void setAccountDao(AccountDao accountDao) {
//        this.accountDao = accountDao;
//    }

    @Override
    public void save() {
        accountDaoImpl22222.save();
    }


    public void startMethod(){
        System.out.println("初始化方法");
    }
    public void endMethod(){
        System.out.println("销毁方法");
    }


    @Override
    public String toString() {
        return "AccountServiceImpl{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", birthday=" + birthday +
                ", myStrs=" + Arrays.toString(myStrs) +
                ", myList=" + myList +
                ", mySet=" + mySet +
                ", myMap=" + myMap +
                ", myProps=" + myProps +
                '}';
    }
}
